
import bpy

import 全局控制.Node.节点和插座基类.bl_节点基类 as 基类
import Core.bl_UI配色 as UI配色

import engine.initLIB.load_dll as engineLib
import ctypes




import random
from bpy.types import Operator
from 全局控制.Node.节点和插座基类.bl_UpdateNode import *









engineLib.flexCAPI.f_创建I32_Array1D_随机采样节点.restype = ctypes.c_bool
engineLib.flexCAPI.f_创建vec3_Array1D_随机采样节点.restype = ctypes.c_bool






E_随机类型枚举 = [
	("TYPE_random", "0~1 浮点数", "", 0),
	("TYPE_uniform", "范围浮点数", "", 1),
	("TYPE_randint", "范围整数数", "", 2),
]


class C_SceneNode_单随机数(基类.C_SN_基类):
	bl_dname = 'bl_node_单随机数'
	bl_label = '单随机数'
	
	m_随机类型 = bpy.props.EnumProperty(items = E_随机类型枚举, name="随机类型", default="TYPE_random" )
	m_区间 = bpy.props.FloatVectorProperty(default=(0,10), size=2)
	def init(self, context):
		super(C_SceneNode_单随机数, self).f_init(context)
		self.inputs.new('C_NodeSocket_f', name='种子')
		self.outputs.new('C_NodeSocket_f', name='value')
		
	def draw_buttons(self, context, layout):
		layout.prop(self, 'm_随机类型')
		if self.m_随机类型 != 'TYPE_random':
			layout.prop(self, 'm_区间')

	def f_input插座Update(self, input插座, 上层Output=None):
		if input插座 :
			if input插座.name == '种子' :
				random.seed(input插座.f_getData())
		super(C_SceneNode_单随机数, self).f_input插座Update(input插座, 上层Output)


	def f_update(self, 是否向下传递=False, input插座=None):
		输出插座 = self.outputs['value']
		if self.m_随机类型 == 'TYPE_random':
			输出插座.f_setData(random.random())
		elif self.m_随机类型 == 'TYPE_uniform':
			输出插座.f_setData(random.uniform(self.m_区间[0], self.m_区间[1]))
		elif self.m_随机类型 == 'TYPE_randint':
			输出插座.f_setData(random.randint(self.m_区间[0], self.m_区间[1]))
		#print('输出插座.f_getData() = ', 输出插座.f_getData())
		super(C_SceneNode_单随机数, self).f_update(是否向下传递)
		return False


class C_NODE_MENU_单随机数(bpy.types.Operator):
	bl_idname = 'node.global_node_single_random'
	bl_label = 'Add 单随机数'
	bl_options = {'REGISTER', 'UNDO'}

	def execute(operator, context):
		operator.use_transform = True
		bpy.ops.node.add_node(type='C_SceneNode_单随机数', use_transform=True)
		return {'FINISHED'}




E_随机多类型枚举 = [
	("TYPE_shuffle", "打乱", "", 0),
	("TYPE_sample", "采样", "", 1),
	("TYPE_序列f", "序列f", "", 2),
	("TYPE_序列i", "序列i", "", 3),
]

def f_update_多随机数生成发生(self, context):
	if self.m_随机类型 == 'TYPE_shuffle' :
		self.inputs['采样数量'].hide = True
	else:
		self.inputs['采样数量'].hide = False

class C_SceneNode_多随机数(基类.C_SN_基类):
	bl_dname = 'bl_node_多随机数'
	bl_label = '多随机数'
	
	m_随机类型 = bpy.props.EnumProperty(items = E_随机多类型枚举, name="随机类型", default="TYPE_shuffle", update=f_update_多随机数生成发生 )
	m_采样数量 = bpy.props.IntProperty(default=1)
	def init(self, context):
		super(C_SceneNode_多随机数, self).f_init(context)
		self.inputs.new('C_NodeSocket_i', name='种子')
		self.inputs.new('C_NS_List_T', name='打乱源')
		self.inputs.new('C_NodeSocket_i', name='采样数量')
		
		self.outputs.new('C_NS_List_T', name='value')

		self.inputs['采样数量'].hide = True

	def draw_buttons(self, context, layout):
		layout.prop(self, 'm_随机类型')
	#	if self.m_随机类型 != 'TYPE_random':
	#		layout.prop(self, 'm_区间')
		
	def f_update(self, 是否向下传递=False, input插座=None):
		输出插座 = self.outputs['value']
		源 = self.inputs['打乱源'].f_getData()
		
		if self.m_随机类型 == 'TYPE_shuffle':
			random.shuffle(源)
			输出插座.f_setData(源)
		elif self.m_随机类型 == 'TYPE_sample':
			采样数量 = self.inputs['采样数量'].f_getData()
			输出插座.f_setData(random.sample(源, 采样数量))
		elif self.m_随机类型 == 'TYPE_序列f':
			采样数量 = self.inputs['采样数量'].f_getData()
			data = [0.0]*采样数量
			for i in range(采样数量):
				data[i] = random.uniform(self.m_区间[0], self.m_区间[1])
			pass
		
		super(C_SceneNode_多随机数, self).f_update(是否向下传递)
		return False

class C_NODE_MENU_多随机数(bpy.types.Operator):
	bl_idname = 'node.global_node_single_mulit_random'
	bl_label = '多随机数'
	bl_options = {'REGISTER', 'UNDO'}

	def execute(operator, context):
		operator.use_transform = True
		bpy.ops.node.add_node(type='C_SceneNode_多随机数', use_transform=True)
		return {'FINISHED'}





















class C_Node_I32_Array1D_随机采样(基类.C_Node_基类):
	bl_dname = 'bl_node_I32_Array1D_随机采样'
	bl_label = 'I32_Array1D_随机采样'
	
	def init(self, context):
		super(C_Node_I32_Array1D_随机采样, self).f_init(context)
		self.inputs.new('C_Socket_I32_Array1D', name='源')
		self.inputs.new('C_Socket_I8_Array1D', name='MASK')
		self.inputs.new('C_Socket_I32_Array1D', name='对比值')

		self.outputs.new('C_Socket_I32_Array1D', name='value')
		
		self.use_custom_color = True
		self.color = UI配色.g_内部节点颜色
		self.f_toCPP()

	def draw_buttons(self, context, layout):
		#layout.prop(self, 'm_随机类型')
		pass

	def f_toCPP(self):
		是否更新 = engineLib.flexCAPI.f_创建I32_Array1D_随机采样节点(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), self.f_getPyObject());
		#if 是否更新 :
		#	self.inputs['源'].f_update()
		#	self.inputs['MASK'].f_update()
		#	self.inputs['对比值'].f_update()
class C_NODE_MENU_I32_Array1D_随机采样(bpy.types.Operator):
	bl_idname = 'node.global_node_i32_a1_sample_random'
	bl_label = 'I32_Array1D_随机采样'
	bl_options = {'REGISTER', 'UNDO'}
	def execute(operator, context):
		operator.use_transform = True
		bpy.ops.node.add_node(type='C_Node_I32_Array1D_随机采样', use_transform=True)
		return {'FINISHED'}











class C_Node_vec3_Array1D_随机采样(基类.C_Node_基类):
	bl_dname = 'bl_node_vec3_Array1D_随机采样'
	bl_label = 'vec3_Array1D_随机采样'
	
	def init(self, context):
		super(C_Node_vec3_Array1D_随机采样, self).f_init(context)
		self.inputs.new('C_Socket_Vec3_Array1D', name='源')
		self.inputs.new('C_Socket_I8_Array1D', name='MASK')
		self.inputs.new('C_Socket_Vec3_Array1D', name='对比值')

		self.outputs.new('C_Socket_Vec3_Array1D', name='value')
		
		self.use_custom_color = True
		self.color = UI配色.g_内部节点颜色
		self.f_toCPP()

	def draw_buttons(self, context, layout):
		#layout.prop(self, 'm_随机类型')
		pass

	def f_toCPP(self):
		是否更新 = engineLib.flexCAPI.f_创建vec3_Array1D_随机采样节点(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), self.f_getPyObject());
		#if 是否更新 :
		#	self.inputs['源'].f_update()
		#	self.inputs['MASK'].f_update()
		#	self.inputs['对比值'].f_update()
class C_NODE_MENU_vec3_Array1D_随机采样(bpy.types.Operator):
	bl_idname = 'node.global_node_vec3_a1_sample_random'
	bl_label = 'vec3_Array1D_随机采样'
	bl_options = {'REGISTER', 'UNDO'}
	def execute(operator, context):
		operator.use_transform = True
		bpy.ops.node.add_node(type='C_Node_vec3_Array1D_随机采样', use_transform=True)
		return {'FINISHED'}
















class C_Node_F32_Array1D_随机打乱(基类.C_Node_基类):
	bl_dname = 'bl_node_F32_Array1D_随机打乱'
	bl_label = 'F32_1D_随机打乱'
	
	def init(self, context):
		super(C_Node_F32_Array1D_随机打乱, self).f_init(context)
		self.inputs.new('C_Socket_F32_Array1D', name='源')
		self.inputs.new('C_Socket_I32', name='种子')
		self.outputs.new('C_Socket_F32_Array1D', name='var')
		
		self.use_custom_color = True
		self.color = UI配色.g_内部节点颜色
		self.f_toCPP()

	def f_toCPP(self):
		是否更新 = engineLib.flexCAPI.f_创建F32_Array1D_随机打乱节点(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), self.f_getPyObject());
		if 是否更新 :
			self.inputs['种子'].f_update()
		
class C_NODE_MENU_F32_Array1D_随机打乱(bpy.types.Operator):
	bl_idname = 'node.global_node_f32_1d_random_intermingle'
	bl_label = 'F32_1D_随机打乱'
	bl_options = {'REGISTER', 'UNDO'}
	def execute(operator, context):
		bpy.ops.node.add_node(type='C_Node_F32_Array1D_随机打乱', use_transform=True)
		return {'FINISHED'}








class C_Node_I32_Array2D_随机打乱(基类.C_Node_基类):
	bl_dname = 'bl_node_I32_Array2D_随机打乱'
	bl_label = 'I32_Array2D_随机打乱'
	
	def init(self, context):
		super(C_Node_I32_Array2D_随机打乱, self).f_init(context)
		self.inputs.new('C_Socket_I32_Array2D', name='源')
		self.inputs.new('C_Socket_I32', name='种子')
		self.outputs.new('C_Socket_I32_Array2D', name='var')
		
		self.use_custom_color = True
		self.color = UI配色.g_内部节点颜色
		self.f_toCPP()


	def f_toCPP(self):
		是否更新 = engineLib.flexCAPI.f_创建I32_Array2D_随机打乱节点(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), self.f_getPyObject());
		if 是否更新 :
			self.inputs['种子'].f_update()
		
class C_NODE_MENU_I32_Array2D_随机打乱(bpy.types.Operator):
	bl_idname = 'node.global_node_i32_a2_random_intermingle'
	bl_label = 'I32_Array2D_随机打乱'
	bl_options = {'REGISTER', 'UNDO'}
	def execute(operator, context):
		bpy.ops.node.add_node(type='C_Node_I32_Array2D_随机打乱', use_transform=True)
		return {'FINISHED'}







classes = (
	C_SceneNode_单随机数,
	C_NODE_MENU_单随机数,

	C_SceneNode_多随机数,
	C_NODE_MENU_多随机数,



	C_Node_I32_Array1D_随机采样,
	C_NODE_MENU_I32_Array1D_随机采样,

	C_Node_vec3_Array1D_随机采样,
	C_NODE_MENU_vec3_Array1D_随机采样,


	C_Node_F32_Array1D_随机打乱,
	C_NODE_MENU_F32_Array1D_随机打乱,

	C_Node_I32_Array2D_随机打乱,
	C_NODE_MENU_I32_Array2D_随机打乱,

)

def register():
	for c in classes:
		bpy.utils.register_class(c)
		

def unregister():
	for c in classes:
		bpy.utils.unregister_class(c)

